#include "includes.h"

void fsm_function(FSM *fsm, FSM_EVENT *event){
    FSM_STATE *state;
    int i;

    event->lock=1;

    state=&(fsm->state_tables[fsm->state_id]);

    for(i=0; state->event_table[i].event<END_EVENT_ID; ++i)
        if(state->event_table[i].event==event->id)
            break;

    if(state->event_table[i].event!=END_EVENT_ID){
        if(state->id!=state->event_table[i].state){
            printf("FSM: leaving state %d...\n", state->id);
            if(state->exit_func!=NULL)
                state->exit_func(event);
        }

        if(state->event_table[i].func!=NULL)
            state->event_table[i].func(event);

        if(state->id!=state->event_table[i].state){
            printf("FSM: entering state %d...\n", state->event_table[i].state);
            if(fsm->state_tables[state->event_table[i].state].enter_func!=NULL)
                fsm->state_tables[state->event_table[i].state].enter_func(event);
            printf("FSM: fsm->state_id=%d, state->event_table[i].state=%d\n", fsm->state_id, state->event_table[i].state);
            fsm->state_id=state->event_table[i].state;
        }
    }else{
        if(state->default_func!=NULL)
            state->default_func(event);
        else if(fsm->default_func!=NULL)
            fsm->default_func(event);
    }

    event->lock=0;
}

void event_buffer_push(FSM_EVENT *a, FSM_EVENT_ID x){
    if(((a->r+1>=STATE_EVENT_BUFFER_MAX)?0:a->r+1)!=a->f){
        a->buffer[a->r]=x;
        a->r=(a->r+1>=STATE_EVENT_BUFFER_MAX)?0:a->r+1;
    }
}

FSM_EVENT_ID event_buffer_pop(FSM_EVENT *a){
    FSM_EVENT_ID tmp;
    if(a->f!=a->r){
        tmp=a->buffer[a->f];
        a->f=(a->f+1>=STATE_EVENT_BUFFER_MAX)?0:a->f+1;
        return tmp;
    }
    return END_EVENT_ID;
}
